home *** CD-ROM | disk | FTP | other *** search
/ Gekikoh Dennoh Club 1 / Gekikoh Dennoh Club Vol. 1 (Japan).7z / Gekikoh Dennoh Club Vol. 1 (Japan) (Track 1).bin / tools / cdc / src / cdrc__.c < prev    next >
Text File  |  1997-02-14  |  26KB  |  973 lines

  1. #include    "_TNB.c"
  2. #define        UNchar        unsigned char
  3. #define        UNint        unsigned int
  4. extern    int    SCSI_ID;
  5. extern    int    SCSI_IDF;
  6. extern    char    SCSI_LUN;
  7. extern    short    CddevSw;        //0: SCSI直接 1:計測IOCTRL
  8. extern    short    CddDrvNo;        //計測IOCTRL用ドライヴNO
  9. extern    short    SWPD;            // /PD がある
  10. extern    short    PauseMode;        // 0:特に 1:ポーズ中
  11. extern    short    Volum;            // ボリューム
  12. extern    short    DeviType;        //5or4=CD-ROM 0x10=MD
  13. extern    short    MD_SeqSecTrak;        // 1;MD セパレートトラック有り
  14. extern    short    MD_MonoTrak;    // -1;MONOトラックのみ,1;有り(禁止),0;なし
  15. extern    short    MD_PlayOnly;    //  0;録再MEDIA 1;再生専用MEDIA
  16.  
  17. extern UNchar REQU_PTR_KEY;
  18. extern UNchar REQU_PTR_ASC;
  19. extern UNchar REQU_PTR_ASCQ;
  20.  
  21. static UNchar MDTOC[256];
  22.  
  23.  
  24.  
  25.  
  26. #define    MULU(o1,o2) ( (unsigned short)(o1)*(unsigned short)(o2) )
  27. #define    MULS(o1,o2) ( (short)(o1)*(short)(o2) )
  28.  
  29. #define    TIMES(TT)    ( __udivsi3( __mulsi3((TT),1000),979) )
  30. #define    TIMESR(TT)    ( __udivsi3( __mulsi3((TT),979),1000) )
  31. //#define    FREMS(TT)    ( __udivsi3( __mulsi3((TT),469),100) )
  32. //#define    FREMSR(TT)    ( __udivsi3( __mulsi3((TT),100)+50,469) )
  33. //#define    FREMS(TT)    ( MULU((TT),4800) / 1024 )
  34. #define    FREMS(TT)    ( FREMS_TABLE[(TT)] )
  35. #define    FREMSR(TT)    ( DIVU((TT)*1024+512,4800) )
  36.  
  37. UNchar    FREMS_TABLE[16]={( 0*4800)/1024,( 1*4800)/1024,( 2*4800)/1024,( 3*4800)/1024,
  38.              ( 4*4800)/1024,( 5*4800)/1024,( 6*4800)/1024,( 7*4800)/1024,
  39.              ( 8*4800)/1024,( 9*4800)/1024,(10*4800)/1024,(11*4800)/1024,
  40.              (12*4800)/1024,(13*4800)/1024,(14*4800)/1024,(15*4800)/1024
  41. };
  42.  
  43.  
  44. /*------------------------------*/
  45. /*    構造体            */
  46. /*------------------------------*/
  47. typedef struct {
  48.     int    fg;            /* 状態 0x11 演奏中,0x12 演奏中断 */
  49.     int    track_no;        /* 曲番号 */    /* 曲番号 ind*0x10000+track */
  50.     int    time;            /* 現在の演奏時間 */
  51.     int    address;        /* 演奏アドレス */
  52.     int    track_long;        /* 演奏中の曲のながさ*/
  53. } PLYINF;
  54.  
  55. extern    int    CddevPauAdd;
  56. extern    int    CddevPlaEnd;
  57. extern    short    CddevPauseD;
  58. extern    int    PlayingTimeMD;
  59.  
  60.  
  61. extern    UNchar buf2k[2336];
  62. extern    UNchar buf32[336];
  63.  
  64. /************************************** 
  65.       低レベルルーチン
  66. **************************************/
  67. /*******************************
  68.    REZEROUNITコマンドを送る
  69. ********************************/
  70. int ZeroUnit()
  71. {
  72. int    r;
  73. StpDsk();
  74. if ( DeviType==0x10 ){
  75.     //MD
  76.     static UNchar com[]={0xD6,0,0,0,0, 0,0,0,0,0};
  77.     r=scsi_cmd( 10, com, 0 );
  78. }
  79. return( scsi_rezerounit(SCSI_ID) );    //LUNは指定なしないこと
  80. }
  81. /*******************************
  82.    ストップコマンドを送る
  83. ********************************/
  84. int StpDsk()
  85. {
  86. int    r;
  87. #if 1
  88.     static UNchar com[]={0x4b,0,0,0,0, 0,0,0,0,0};
  89.     return( scsi_cmd( 10, com, 0 ) );
  90. #else
  91.     if ( CddevSw==0 ){    //0: SCSI直接 1:計測IOCTRL
  92.         static UNchar com[]={0x4b,0,0,0,0, 0,0,0,0,0};
  93.         return( scsi_cmd( 10, com, 0 ) );
  94.     } else {
  95.         #if 1
  96.             cdd_ioctrl(0x8004,buf32);
  97.             //if ( buf32[0]!=0 )    /*演奏している?*/
  98.             //    return(-1);
  99.             CddevPauAdd= buf32[8] * 0x10000 + buf32[9] * 0x100 + buf32[10];
  100.         #else
  101.             extern    PLYINF plyinf;
  102.             //if ( plyinf.fg!=0x11 )    /*演奏している?*/
  103.             //    return(-1);
  104.             ChkPly( &plyinf );
  105.             CddevPauAdd=plyinf.address;
  106.         #endif
  107.         cdd_ioctrl(0x8003,buf32);//停止
  108.         CddevPauseD=1;
  109.         //buf32[0]=0;
  110.         //cdd_ioctrl(0x8005,buf32);//停止
  111.         return(0);
  112.     }
  113. #endif
  114. }
  115. /*******************************
  116.     Resume コマンドを送る
  117. ********************************/
  118. int Resume()
  119. {
  120. #if 1
  121.     static UNchar com[]={0x4b,0,0,0,0, 0,0,0,1,0};
  122.     return( scsi_cmd( 10, com, 0 ) );
  123. #else
  124.     if ( CddevSw==0 ){    //0: SCSI直接 1:計測IOCTRL
  125.         static UNchar com[]={0x4b,0,0,0,0, 0,0,0,1,0};
  126.         return( scsi_cmd( 10, com, 0 ) );
  127.     } else {
  128.         int    i;
  129.         #if 0
  130.             cdd_ioctrl(0x8004,buf32);
  131.             if ( buf32[0]!=1 || CddevPauAdd==0 )    /*停止中?*/
  132.                 return(-1);
  133.         #else
  134.             //extern    PLYINF plyinf;
  135.             //if ( plyinf.fg!=0x12 )    /*演奏している?*/
  136.             //    return(-1);
  137.         #endif
  138.         i=CddevPauAdd;
  139.         CddevPauAdd=0;
  140.         CddevPauseD=0;
  141.         return( PlyDsk( i,CddevPlaEnd ) );
  142.     }
  143. #endif
  144. }
  145. /********************************
  146.        演奏状態を調べる
  147. *********************************/
  148. int ChkPly( PLYINF *plyinf )
  149. {
  150. int    i,j,r;
  151. if ( DeviType!=0x10 ){
  152.     if ( CddevSw==0 ){    //0: SCSI直接 1:計測IOCTRL
  153.         static UNchar com[]={
  154.                 0x42,        /* Read Sub-Channel Command */
  155.                 0x02,        /* Set MSF Bit */
  156.                 0x40,        /* Set SubQ Bit */
  157.                 0x01,        /* CD-ROM Current Posision */
  158.                 0,
  159.                 0,
  160.                 0,
  161.                 0,
  162.                 16,        /* Allocation Length */
  163.                 0
  164.         };
  165.         if ( scsi_cmd( 10,com, 16, buf32 )!=0 )
  166.             return(-1);
  167.         plyinf->fg       = buf32[1]&0x1F;            /* 状態 */
  168.         plyinf->track_no = buf32[6] + buf32[7]*0x10000;    /* 曲番号 ind*0x10000+track */
  169.         plyinf->time     = (*(UNint*)&buf32[12]) & 0xFFFFFF;
  170.         plyinf->address  = (*(UNint*)&buf32[8]) & 0xFFFFFF;
  171.         //plyinf->time     = buf32[13] * 0x10000 + buf32[14] * 0x100 + buf32[15];
  172.         //plyinf->address  = buf32[9]  * 0x10000 + buf32[10] * 0x100 + buf32[11];
  173.     } else {
  174.         cdd_ioctrl(0x8004,buf32);
  175.         if ( buf32[0]==0 && buf32[1]==0 )/*CD入っていないらしい*/
  176.             return(-1);
  177.         #if 0
  178.             if ( buf32[0]==0 && buf32[1]==1 )
  179.                 plyinf->fg = 0x11;
  180.             else if ( buf32[0]==1 && buf32[1]==1 )
  181.                 plyinf->fg = 0x13;
  182.             else    plyinf->fg = 0x15;
  183.         #endif
  184.         if ( CddevPauseD==0 ){    // 0:特に 1:ポーズ中
  185.             if ( buf32[0]==0 && buf32[1]==1 )
  186.                 plyinf->fg = 0x11;
  187.             else if ( buf32[0]==1 && buf32[1]==1 )
  188.                 plyinf->fg = 0x13;
  189.             else    plyinf->fg = 0x15;
  190.         } else    plyinf->fg = 0x12;
  191.         plyinf->track_no = buf32[2] + buf32[3]*0x10000;    /* 曲番号 ind*0x10000+track */
  192.         plyinf->time     = (*(UNint*)&buf32[4])/0x100;
  193.         plyinf->address  = (*(UNint*)&buf32[8])/0x100;
  194.         //plyinf->time     = buf32[4] * 0x10000 + buf32[5] * 0x100 + buf32[6];
  195.         //plyinf->address  = buf32[8] * 0x10000 + buf32[9] * 0x100 + buf32[10];
  196.     }
  197. } else {
  198.     //MD
  199.     static UNchar com[]={ 0xD7,0,0,0,0, 0,0,0,4,0 };
  200.     //extern    int    (*pListLong)[];    // ながさ時間
  201.     com[1]=0;
  202.     PlayingTimeMD=-1;
  203.     for(i=0;i<3;i++){
  204.         r=scsi_cmd( 10, com, 4, buf32 );
  205.         if ( r==0 )
  206.             break;
  207.         if ( (REQU_PTR_KEY&0xF)==5 ){
  208.             //コマンドエラー と言うことは・・・
  209.             i=scsi_testunit(SCSI_IDF);
  210.             if ( REQU_PTR_ASC==0x3a )    //メディアが入っていない!!
  211.                 return(-1);
  212.             plyinf->fg = 0x13;            /* 停止 */
  213.             return(0);
  214.         }
  215.         if ( (REQU_PTR_KEY&0xF)!=2 )
  216.             break;
  217.     }
  218.     if ( r!=0 ){
  219.         plyinf->fg = 0x13;            /* 停止 */
  220.     } else {
  221.         if ( scsi_testunit(SCSI_IDF)==2 ){
  222.             if ( (REQU_PTR_KEY&0xF)==2 && REQU_PTR_ASC==0x00 )
  223.                 plyinf->fg = REQU_PTR_ASCQ;
  224.         } else {
  225.             // testunit で 2 出ないと困る・・・
  226.             plyinf->fg = 0x11;            /* 演奏中 */
  227.         }
  228.     }
  229.     r=*(int*)buf32;
  230.     if ( MD_PlayOnly==0 )        //  0;録再MEDIA 1;再生専用MEDIA
  231.         r-=0x320000;
  232.     r=r/0x100;
  233.     r=(r/0x100*0x20)+(r&0x1F);            //アドレス
  234.     r=TIMES(r);                    //補正後のアドレス
  235.     //-- 相対アドレス(MSF型に変換)
  236.     plyinf->address  = DIVU(r/0x10,60)*0x10000 + MODU(r/0x10,60)*0x100 + FREMS(r&0xF);
  237.     if ( MD_MonoTrak!=0 ){            // -1;MONOトラックのみ,1;有り(禁止),0;なし
  238.         //モノラルトラック
  239.         plyinf->address = addtime( plyinf->address,plyinf->address );
  240.     }
  241.     //-- 演奏開始からの時間
  242.     com[1]=1;
  243.     if ( scsi_cmd( 10, com, 4, &PlayingTimeMD ) )
  244.         if ( scsi_cmd( 10, com, 4, &PlayingTimeMD ) )
  245.             if ( scsi_cmd( 10, com, 4, &PlayingTimeMD ) )
  246.                 PlayingTimeMD=-1;
  247.     //-- アドレス(MSF型に変換)
  248.     // track_no & time も計算
  249.     CPD_MDSUB( plyinf );        //adのみから計算
  250.     if ( MD_MonoTrak!=0 ){            // -1;MONOトラックのみ,1;有り(禁止),0;なし
  251.         //モノラルトラック
  252.         plyinf->time = addtime( plyinf->time,plyinf->time );
  253.     }
  254. }
  255. return(0);
  256. }
  257. /*********************************
  258.   (トラック)演奏開始からのS(MD専用)
  259. *********************************/
  260. int    MDPlayingTimeChk()
  261. {
  262. static UNchar com[]={ 0xD7,1,0,0,0, 0,0,0,4,0 };
  263. int    tim;
  264. if ( DeviType!=0x10 )
  265.     return(0);
  266. if ( scsi_cmd( 10, com, 4, &tim ) )
  267.     if ( scsi_cmd( 10, com, 4, &tim ) )
  268.         return(0);
  269. if ( tim<10 )
  270.     return(-1);
  271. return(0);
  272. }
  273. /*********************************
  274.     演奏させる
  275. *********************************/
  276. int PlyDsk( int start , int stop )
  277. {
  278. UNchar com[12];
  279. if ( DeviType!=0x10 ){
  280.     if ( CddevSw==0 ){    //0: SCSI直接 1:計測IOCTRL
  281.         #if 1
  282.             com[0] = 0x47;                /* Play Audio MSF Command */
  283.             com[1] = 0;
  284.             com[2] = 0;
  285.             com[3] = ( start / 0x10000 ) & 0xff;
  286.             com[4] = ( start / 0x100 )   & 0xff;
  287.             com[5] =   start             & 0xff;
  288.             com[6] = ( stop / 0x10000 )  & 0xff;
  289.             com[7] = ( stop / 0x100 )    & 0xff;
  290.             com[8] =   stop              & 0xff;
  291.             com[9] = 0;
  292.             return( scsi_cmd( 10, com, 0 ) );
  293.         #else
  294.             int s,e;
  295.             s=MULU((start/0x10000)&0xff,75*60)
  296.                 +MULU((start/0x100)&0xff,75)
  297.                 +(start&0xff);
  298.             e=MULU((stop/0x10000)&0xff,75*60)
  299.                 +MULU((stop/0x100)&0xff,75)
  300.                 +(stop&0xff);
  301.             e=e-s;
  302.             com[0] = 0xA5;                /* Play Audio Command */
  303.             com[1] = 0;
  304.             *(int*)&(com[2]) = s;
  305.             *(int*)&(com[6]) = e;
  306.             com[10] = 0;
  307.             com[11] = 0;
  308.             return( scsi_cmd( 12, com, 0 ) );
  309.         #endif
  310.  
  311.  
  312.     } else {
  313.         com[0] = ( start / 0x10000 ) & 0xff;
  314.         com[1] = ( start / 0x100 )   & 0xff;
  315.         com[2] =   start             & 0xff;
  316.         com[3] = 0;
  317.         com[4] = ( stop / 0x10000 )  & 0xff;
  318.         com[5] = ( stop / 0x100 )    & 0xff;
  319.         com[6] =   stop              & 0xff;
  320.         com[7] = 0;
  321.         cdd_ioctrl(0x8001,com);
  322.         CddevPlaEnd=stop;
  323.         CddevPauseD=0;
  324.         return( 0 );
  325.     }
  326. } else {
  327.     // MD                        ★★★★怪しいい・・・
  328.     int    i,j,l,sa,ea;
  329.     // スタートアドレス : MSF -> 論理アドレス
  330.     sa = MDMSF2ADDS(start);
  331.     sa+=1;
  332.     // エンドアドレス : MSF -> 論理アドレス
  333.     ea = MDMSF2ADDS(stop);
  334.     // 長さ計算
  335.     l=ea-sa  -1;
  336.     // CDB 制作
  337.     com[0] = 0x45;                /* Play Audio ADDS Command */
  338.     com[1] = 0;
  339.     com[2] = 0;
  340.     com[3] = ( sa / 0x10000 ) & 0xff;
  341.     com[4] = ( sa / 0x100 )   & 0xff;
  342.     com[5] =   sa             & 0xff;
  343.     com[6] = 0;
  344.     com[7] = ( l  / 0x100 )   & 0xff;
  345.     com[8] =   l              & 0xff;
  346.     com[9] = 0;
  347.     return( scsi_cmd( 10, com, 0 ) );
  348. }
  349. }
  350. /*+++++++++*/
  351. int PlyDsk_hf( int start , int stop )
  352. {
  353. /* Play Audio MSF  Command */
  354. UNchar com[10];
  355. if ( DeviType!=0x10 ){
  356.     if ( CddevSw==0 ){    //0: SCSI直接 1:計測IOCTRL
  357.         com[0] = 0x47;                /* Play Audio MSF Command */
  358.         com[1] = 0;
  359.         com[2] = 0;
  360.         com[3] = ( start / 0x10000 ) & 0xff;
  361.         com[4] = ( start / 0x100 )   & 0xff;
  362.         com[5] =   start             & 0xff;
  363.         com[6] = ( stop / 0x10000 )  & 0xff;
  364.         com[7] = ( stop / 0x100 )    & 0xff;
  365.         com[8] =   stop              & 0xff;
  366.         com[9] = 0;
  367.         return( scsi_cmd_hf( 10, com, 0 ) );
  368.     }
  369.     return( PlyDsk( start,stop ) );
  370. } else {
  371.     // MD                        ★★★★怪しいい・・・
  372.     int    i,j,l,sa,ea;
  373.     // スタートアドレス : MSF -> 論理アドレス
  374.     sa = MDMSF2ADDS(start);
  375.     sa+=1;
  376.     // エンドアドレス : MSF -> 論理アドレス
  377.     ea = MDMSF2ADDS(stop);
  378.     // 長さ計算
  379.     l=ea-sa -1;
  380.     // CDB 制作
  381.     com[0] = 0x45;                /* Play Audio ADDS Command */
  382.     com[1] = 0;
  383.     com[2] = 0;
  384.     com[3] = ( sa / 0x10000 ) & 0xff;
  385.     com[4] = ( sa / 0x100 )   & 0xff;
  386.     com[5] =   sa             & 0xff;
  387.     com[6] = 0;
  388.     com[7] = ( l  / 0x100 )   & 0xff;
  389.     com[8] =   l              & 0xff;
  390.     com[9] = 0;
  391.     return( scsi_cmd_hf( 10, com, 0 ) );
  392. }
  393. }
  394. /*+++++++++++++*/
  395. int    MDMSF2ADDS(ad)
  396. int    ad;
  397. {
  398. int    i,j,r;
  399. i=(ad/0x10000)&0xFF;
  400. j=(ad/0x100)  &0xFF;
  401. r=(MULU(i,60)+j)*0x10 + FREMSR(ad&0xFF);
  402. r=TIMESR(r);                //MD 上のアドレスに変換
  403. return( r );
  404. }
  405. /***********************************
  406.     トラック演奏(MD用・・・)
  407. ************************************/
  408. int PlyDskTrack( int start , int stop )
  409. {
  410. static UNchar com[]={0x48,0,0,0x00,0, 0,0,0x00,0,0};
  411. com[4] = start;
  412. com[7] = stop;
  413. return( scsi_cmd( 10, com, 0 ) );
  414. }
  415. /*++++*/
  416. int PlyDskTrack_hf( int start , int stop )
  417. {
  418. static UNchar com[]={0x48,0,0,0x00,0, 0,0,0x00,0,0};
  419. com[4] = start;
  420. com[7] = stop;
  421. return( scsi_cmd_hf( 10, com, 0 ) );
  422. }
  423. /***********************************
  424.   曲数と最終演奏アドレスを求める
  425. ************************************/
  426. int RedTOC(leadout_address,min_,max_)
  427. int    *leadout_address,*min_,*max_;
  428. {
  429. int    l;
  430. if ( DeviType!=0x10 ){
  431.     static UNchar    com[]={
  432.         /* Leadout Track Address get & Min. Max Track get */
  433.             0x43,                    /* scsi2 ReadTOC Command */
  434.             0x02,                    /* Set MSF Bit */
  435.             0,
  436.             0,
  437.             0,
  438.             0,
  439.             0xaa,                    /* LeadoutOut Track */
  440.             0,
  441.             12,                    /* Allocation Length */
  442.             0
  443.     };
  444.     if ( CddevSw==0 ){    //0: SCSI直接 1:計測IOCTRL
  445.         if( scsi_cmd( 10, com, 12, buf32 )!=0 )
  446.             return(-1);
  447.         *leadout_address = (*(UNint*)&buf32[8]) & 0xFFFFFF;
  448.         //*leadout_address = buf32[9] * 0x10000 + buf32[10] * 0x100 + buf32[11];
  449.         *min_ = buf32[2];                /* Min. Track */
  450.         *max_ = buf32[3];                /* Max. Track */
  451.     } else {
  452.         cdd_ioctrl(0x8000,buf32);
  453.         *leadout_address = (*(UNint*)&buf32[2]) / 0x100;
  454.         //*leadout_address = buf32[2] * 0x10000 + buf32[3] * 0x100 + buf32[4];
  455.         *min_ = buf32[0];                /* Min. Track */
  456.         *max_ = buf32[1];                /* Max. Track */
  457.     }
  458. } else {
  459.     static UNchar com[]={0xD1,0x00,0,0,0,0x00,0,0x09,0x20,0};
  460.     int    i,j,r,o;
  461.     int    t,tt;
  462.     int    lst[100];
  463.     int    lstl[100];
  464.     UNchar    *fg;
  465.     *min_ = 1;                /* Min. Track */
  466.     *max_ = 1;                /* Max. Track */
  467.     *leadout_address=0;
  468.     MD_PlayOnly=0;        //  0;録再MEDIA 1;再生専用MEDIA
  469.     com[0]=0xD1;
  470.     if ( (r=scsi_cmd( 10, com, 2336, buf2k ))!=0 )
  471.         r=scsi_cmd( 10, com, 2336, buf2k );
  472.     if ( r==2 ){
  473.         if ( (REQU_PTR_KEY&0xF)==5 && REQU_PTR_ASC==0x20 && REQU_PTR_ASCQ==0 ){
  474.             MD_PlayOnly=1;        //  0;録再MEDIA 1;再生専用MEDIA
  475.             com[0]=0xD4;
  476.             if ( (r=scsi_cmd( 10, com, 2336, buf2k ))!=0 )
  477.                 if ( (r=scsi_cmd( 10, com, 2336, buf2k ))!=0 )
  478.                     return(-1);
  479.         } else {
  480.             return(-1);
  481.         }
  482.                 //if ( (REQU_PTR_KEY&0xF)==2 && REQU_PTR_ASC==0x57 && REQU_PTR_ASCQ==0 )
  483.                 //    return(-1);
  484.     } else if ( r!=0 ){
  485.         return(-1);
  486.     }
  487.     *max_ = l = buf2k[0x0F];            /* Max. Track */
  488.     if ( MD_PlayOnly==0 ){        //  0;録再MEDIA 1;再生専用MEDIA
  489.         //====== 録再 ======
  490.         //----- フラグクリア
  491.         fg=lstl; //チョット借りる
  492.         j=0xFFFFFF;
  493.         for(t=1;t<=254;t++){
  494.             fg[t]=0;
  495.             // ついでに一番若いセクタを指しているテーブルを探す
  496.             o=0x130+(t-1)*8;
  497.             i=buf2k[o]*0x10000 + buf2k[o+1]*0x100 + buf2k[o+2];
  498.             if ( i>=0xC800 && i<j ){
  499.                 j=i;
  500.                 tt=t;
  501.             }
  502.         }
  503.         //----- 曲の列びをチェック
  504.         for(t=1;t<=l;t++){
  505.             j=buf2k[0x20+t-1];    //ofset
  506.             o=0x130+(j-1)*8;    //ofset
  507.             // +7 のバイトを見てみる
  508.             if ( buf2k[o+7]==0 && fg[j]==0 ){
  509.                 MDTOC[t]=j;
  510.                 fg[j]=1;
  511.                 continue;
  512.             }
  513.             // 0以外。未使用FATかな?
  514.             // 未使用のようなので、
  515.             if ( j!=t ){
  516.                 // TrkNo と テーブルが違う場合
  517.                 //  TrkNo で見てみる
  518.                 o=0x130+(t-1)*8;    //ofset
  519.                 if ( buf2k[o+7]==0 && fg[t]==0 ){
  520.                     // 使えるようだ
  521.                     MDTOC[t]=t;
  522.                     fg[t]=1;
  523.                     continue;
  524.                 }
  525.             }
  526.             // 頭の方から使っていない番号を見つける
  527.             // ★★これでもない場合...間違っているわけだ・・・
  528.             for(i=1;i<=254;i++){
  529.                 if ( fg[i]!=0 )
  530.                     continue;
  531.                 o=0x130+(i-1)*8;    //ofset
  532.                 if ( buf2k[o+7]==0 ){
  533.                     // 使えるようだ
  534.                     MDTOC[t]=i;
  535.                     fg[i]=1;
  536.                     break;
  537.                 }
  538.             }
  539.         }
  540.         if ( fg[tt]==0 ){
  541.             // 一番若いセクタのが使われていない!
  542.             // 一番最初の曲に当てがう
  543.             MDTOC[1]=tt;
  544.         }
  545.     } else {
  546.         //====== 再生専用 ======
  547.         ;
  548.     }
  549.  
  550.     //fprintf_(1,"%3\r\n",tt);
  551.  
  552.     if ( Music_inf_all( 1,l,lst,lstl ) )
  553.         if ( Music_inf_all( 1,l,lst,lstl ) )
  554.             return(-1);
  555.     j=0;
  556.     for(i=1;i<=l;i++)
  557.         j=addtime_( j,lstl[i] );
  558.     *leadout_address = j;
  559. }
  560. return(0);
  561. }
  562. /*************************************
  563.     演奏アドレスを求める
  564.         [MD] MD の場合、先にRedTOCを実
  565.         行しておかなければならないが、
  566.         問題無い様
  567. ***************************************/
  568. int    Music_inf( track_no,start_address,track_long )
  569. int    track_no;
  570. int    *start_address,*track_long;
  571. {
  572. int    i,oo,o;
  573. int    j,l,r;
  574. int    fg;
  575. if ( DeviType!=0x10 ){
  576.     static UNchar com[]={
  577.             0x43,                    /* scsi2 ReadTOC Command */
  578.             0x02,                    /* Set MSF Bit */
  579.             0,
  580.             0,
  581.             0,
  582.             0,
  583.              00,                    /* Set Start Track */
  584.             0,
  585.             12,                    /* Allocation Length */
  586.             0
  587.     };
  588.     if ( CddevSw==0 ){    //0: SCSI直接 1:計測IOCTRL
  589.         com[6] = (UNchar)track_no;        /* Set Start Track */
  590.         if( scsi_cmd( 10, com, 12, buf32 ) != 0 )
  591.             return(-1);
  592.         *start_address = (*(UNint*)&buf32[8]) & 0xFFFFFF;
  593.         //*start_address = buf32[9] * 0x10000 + buf32[10] * 0x100 + buf32[11];
  594.         if ( (buf32[5]&0b0100)!=0 )//データだ
  595.             *(UNint*)start_address |= (UNint)0x80000000;
  596.     } else {
  597.         cdd_ioctrl(0x8000,buf2k);
  598.         i=(track_no-1)*4+6;
  599.         *start_address = (*(UNint*)&buf2k[i]) / 0x100;
  600.         //*start_address = buf2k[i] * 0x10000 + buf2k[i+1] * 0x100 + buf2k[i+2];
  601.         if ( buf2k[i+3]!=0 )//データだ
  602.             *(UNint*)start_address |= (UNint)0x80000000;
  603.     }
  604. } else {
  605.     static UNchar com[]={0xD1,0x00,0,0,0, 0x00,0,0x09,0x20,0};
  606.     if ( MD_PlayOnly==0 )        //  0;録再MEDIA 1;再生専用MEDIA
  607.         com[0]=0xD1;
  608.     else    com[0]=0xD4;
  609.     if ( scsi_cmd( 10, com, 2336, buf2k )!=0 ){
  610.         if ( scsi_cmd( 10, com, 2336, buf2k )!=0 ){
  611.             *start_address = 0;
  612.             if ( track_long!=0 )
  613.                 *track_long = 0;
  614.             return(-1);
  615.         }
  616.     }
  617.     if ( MD_PlayOnly==0 ){        //  0;録再MEDIA 1;再生専用MEDIA
  618.         //===== 録音再生 ======
  619.         //o=buf2k[0x20-1+track_no];    //ofset
  620.         //o=track_no;
  621.  
  622.           o=MDTOC[track_no];
  623.  
  624.         o=0x130+(o-1)*8;    //ofset
  625.         //セクタの先頭
  626.         //j=buf2k[o]*0x10000+buf2k[o+1]*0x100+buf2k[o+2];
  627.         j=(*(int*)&buf2k[o])/0x100;
  628.         j=(j-0xC800)/32;        //定数?
  629.         i=TIMES(j);
  630.         i=DIVU(i/0x10,60)*0x10000 + MODU(i/0x10,60)*0x100 + FREMS(i&0x0F);
  631.         *start_address = i;
  632.         if ( track_long!=0 ){
  633.             //i=buf2k[o+4]*0x10000+buf2k[o+4+1]*0x100+buf2k[o+4+2];
  634.             i=(*(int*)&buf2k[o+4])/0x100;
  635.             i=(i-0xC800)/32;        //定数?
  636.             l=TIMES( i-j );
  637.             fg=0;
  638.             if ( buf2k[o+7]!=0 ){
  639.                 //続きのセクタがある!?
  640.                 //★今のところ、判らない?!
  641.                 //  書かれている数値が続きセクタ+αとする・・・
  642.     
  643.                 oo=buf2k[o+7];
  644.                 oo=0x120+(oo)*8;    //ofset
  645.     
  646.                 //セクタの先頭
  647.                 //j=buf2k[oo]*0x10000+buf2k[oo+1]*0x100+buf2k[oo+2];
  648.                 j=(*(int*)&buf2k[oo])/0x100;
  649.                 j=(j-0xC800)/32;        //定数?
  650.                 //セクタの終わり
  651.                 //i=buf2k[oo+4]*0x10000+buf2k[oo+4+1]*0x100+buf2k[oo+4+2];
  652.                 i=(*(int*)&buf2k[oo+4])/0x100;
  653.                 i=(i-0xC800)/32;        //定数?
  654.                 i=TIMES( i-j );
  655.                 l+=i;
  656.                 fg=-1;
  657.             }
  658.             i=DIVU(l/0x10,60)*0x10000 + MODU(l/0x10,60)*0x100 + FREMS(l&0x0F);
  659.             *track_long= i;
  660.             if ( (buf2k[o+3]&0x0F)==4 ){
  661.                 // MONO トラック!
  662.                 *start_address = addtime( *start_address,*start_address);
  663.                 *track_long = addtime( *track_long,*track_long );
  664.                 *track_long |= 0x20000000;    //MONOトラックフラグ
  665.             }
  666.             if ( fg!=0 )
  667.                 *track_long |= 0x40000000;    //セパレートセクタフラグ
  668.         }
  669.         if ( (buf2k[o+3]&0xF0)==0xA0 ){
  670.             // デジタル録音されている   $Ax
  671.             *start_address |= 0x40000000;    //デジタルフラグ
  672.         }
  673.     } else {
  674.         //===== 再生専用 ======
  675.         o=0x120+(track_no)*8;    //ofset
  676.         j=(*(int*)&buf2k[o])/0x100;
  677.         j=(j-0x01F0)/32;        //定数?
  678.         i=TIMES(j);
  679.         i=DIVU(i/0x10,60)*0x10000 + MODU(i/0x10,60)*0x100 + FREMS(i&0x0F);
  680.         *start_address = i;
  681.         if ( track_long!=0 ){
  682.             //i=buf2k[o+4]*0x10000+buf2k[o+4+1]*0x100+buf2k[o+4+2];
  683.             i=(*(int*)&buf2k[o+4])/0x100;
  684.             i=(i-0x01F0)/32;        //定数?
  685.             l=TIMES( i-j );
  686.             i=DIVU(l/0x10,60)*0x10000 + MODU(l/0x10,60)*0x100 + FREMS(l&0x0F);
  687.             *track_long= i;
  688.             if ( (buf2k[o+3]&0x0F)==4 ){
  689.                 // MONO トラック!
  690.                 *start_address = addtime( *start_address,*start_address);
  691.                 *track_long = addtime( *track_long,*track_long );
  692.                 *track_long |= 0x20000000;    //MONOトラックフラグ
  693.             }
  694.         }
  695.         if ( (buf2k[o+3]&0xF0)==0xA0 ){
  696.             // デジタル録音されている   $Ax
  697.             *start_address |= 0x40000000;    //デジタルフラグ
  698.         }
  699.     }
  700. }
  701. return(0);
  702. }
  703. /*++++++++++*/
  704. int    Music_inf_all( min,max,lst,lstl )
  705. int    min,max;
  706. int    *lst,*lstl;
  707. {
  708. int    i;
  709. int    t;
  710. if ( DeviType!=0x10 ){
  711.     if ( CddevSw==0 ){    //0: SCSI直接 1:計測IOCTRL
  712.         for(t=min;t<=max;t++){
  713.             if ( Music_inf( t,&lst[t],0 )!=0 )
  714.                 return(-1);
  715.         }
  716.     } else {
  717.         cdd_ioctrl(0x8000,buf2k);
  718.         for(t=min;t<=max;t++){
  719.             i=(t-1)*4+6;
  720.             lst[t]= (*(UNint*)&buf2k[i]) / 0x100;
  721.             //lst[t]= buf2k[i] * 0x10000 + buf2k[i+1] * 0x100 + buf2k[i+2];
  722.             if ( buf2k[i+3]!=0 )//データだ
  723.                 (UNint)lst[t] |= (UNint)0x80000000;
  724.         }
  725.     }
  726. } else {
  727.     for(t=min;t<=max;t++){
  728.         if ( Music_inf( t,&lst[t],&lstl[t] )!=0 )
  729.             return(-1);
  730.     }
  731. }
  732. return(0);
  733. }
  734. /*************************************
  735.     トラックの文字をゲット
  736.             (文字数は 1700 の可能性有り)
  737. ***************************************/
  738. int GetTrackName( int track_no, UNchar *nb )
  739. {
  740. static UNchar com[]={0xD1,0x00,0,0,0, 0x01,0,0x09,0x20,0};
  741. int    i,j,r,o;
  742. UNchar    *s;
  743. nb[0]=0;
  744. if ( MD_PlayOnly==0 )        //  0;録再MEDIA 1;再生専用MEDIA
  745.     com[0]=0xD1;
  746. else    com[0]=0xD4;
  747. if ( scsi_cmd( 10, com, 2336, buf2k )!=0 )
  748.     if ( scsi_cmd( 10, com, 2336, buf2k )!=0 )
  749.         return(-1);
  750. if ( MD_PlayOnly==0 ){        //  0;録再MEDIA 1;再生専用MEDIA
  751.     o=buf2k[0x20+track_no];    //ofset
  752.     if ( track_no!=0 && o==0 )
  753.         return(-1);
  754.     j=0;
  755.     for(;;){
  756.         s=&buf2k[0x120+o*8];        //ofset
  757.         for(i=0;i<7;i++){
  758.             if ( j<39 )
  759.                 nb[j++]=*s++;
  760.         }
  761.         o=buf2k[0x120+o*8 +7];        //次の場所
  762.         if ( o==0 || j>=39 )
  763.             break;
  764.     }
  765.     nb[j]=0;
  766. } else {
  767.     o=buf2k[0x20+track_no];    //ofset
  768.     if ( track_no!=0 && o==0 )
  769.         return(-1);
  770.     s=&buf2k[0x120+o*8];        //ofset
  771.     for(j=0;j<39;j++){
  772.         if ( (nb[j]=*s++)==0 )
  773.             break;
  774.     }
  775.     nb[j]=0;
  776. }
  777. return(0);
  778. }
  779. /*************************************
  780.     STARTSTOP
  781. ***************************************/
  782. int    scsi_startstop(cm)
  783. int        cm;
  784. {
  785. static UNchar com[6]={0x1B,0x1,0,0,0,0};
  786. if ( cm==2 && DeviType==0x10 ){
  787.     //MD
  788.     static UNchar com[]={0xD6,0,0,0,0, 0,0,0,0,0};
  789.     scsi_cmd( 10, com, 0 );
  790. }
  791. com[4]=cm;
  792. return( scsi_cmd( 6, com, 0 ) );
  793. }
  794. /*************************************
  795.     STARTSTOP__
  796. ***************************************/
  797. void    ejeload()
  798. {
  799. static UNchar com[6]={0x1B,0x1,0,0,0,0};
  800. short    i;
  801. com[4]=2;
  802. scsi_cmd( 6, com, 0 );
  803. i=*(short *)0xe9a005;        //wait
  804. i=*(short *)0xe9a005;
  805. i=*(short *)0xe9a005;
  806. i=*(short *)0xe9a005;
  807. i=*(short *)0xe9a005;
  808. i=*(short *)0xe9a005;
  809. com[4]=3;
  810. scsi_cmd( 6, com, 0 );
  811. }
  812. /*-------------------------------------------------------------
  813.         ボリューム,パン関係
  814. ---------------------------------------------------------------*/
  815. #define CDROMPage    0x0e    // modesense/selectの時のページ
  816. #define MDDATAPage    0x21    // modesense/selectの時のページ
  817.  
  818. #define SD_CURRENT    0x00    // sense data current
  819. #define SD_CHANGE    0x40    // sense data changeable
  820. #define SD_DEFAULT    0x80    // sense data defualt
  821. #define SD_SAVE        0xc0    // sense data saveable
  822. /************************************
  823.     今のVOL値を拾う
  824. ************************************/
  825. int    NowVol()
  826. {
  827. int    pg;
  828. UNchar    buf[16+12];
  829. pg=( DeviType!=0x10 )? CDROMPage : MDDATAPage;
  830. if ( scsi_modesense( pg|SD_CURRENT,16+12,SCSI_IDF,buf )<0 )
  831.     return(-1);
  832. return(buf[9+12]);    //ポート0のボリューム
  833. }
  834. /************************************
  835.     VOL値を変更
  836. ************************************/
  837. int    ChnVol(vv)
  838. int    vv;
  839. {
  840. int    i;
  841. i=ChnVol_(vv);
  842. if ( i>=0 )
  843.     Volum=vv;
  844. return(i);
  845. }
  846. /*+++++++*/
  847. int    ChnVol_(vv)
  848. int    vv;
  849. {
  850. UNchar    chk[16+12];
  851. UNchar    buf[16+12];
  852. int    i,j,r,pg;
  853. pg=( DeviType!=0x10 )? CDROMPage : MDDATAPage;
  854. if ( scsi_modesense( pg|SD_CURRENT,16+12,SCSI_IDF,buf )<0 )
  855.     return(-1);
  856. r=buf[9+12];    //ポート0のボリューム
  857. if ( scsi_modesense( pg|SD_CHANGE,16+12,SCSI_IDF,chk )<0 )
  858.     return(-1);
  859. for(i=0;i<4;i++){
  860.     j=9+12+i*2;
  861.     if ( chk[j]==0xFF )
  862.         buf[j]=vv;
  863. }
  864. buf[2+12]=4;
  865. buf[8]= buf[9]= buf[10]= buf[11]= 0;
  866. if ( scsi_modeselect(0x10,16+4,SCSI_IDF,&buf[8])<0 )
  867.     return(-1);
  868. return(r);
  869. }
  870. /************************************
  871.     CDROMのデフォルト値
  872. ************************************/
  873. int    DefVol()
  874. {
  875. UNchar    buf[16+12];
  876. int    i,j,r,pg;
  877. pg=( DeviType!=0x10 )? CDROMPage : MDDATAPage;
  878. if ( scsi_modesense( pg|SD_DEFAULT,16+12,SCSI_IDF,buf )<0 )
  879.     return(-1);
  880. return( buf[9+12] );    //ポート0のボリューム
  881. }
  882. /************************************
  883.     ステレオ <-> モノラル
  884. ************************************/
  885. int    ChnStMono()
  886. {
  887. UNchar    buf[16+12];
  888. int    i,j,r,pg;
  889. pg=( DeviType!=0x10 )? CDROMPage : MDDATAPage;
  890. if ( scsi_modesense( pg|SD_CURRENT,16+12,SCSI_IDF,buf )<0 )
  891.     return(-1);
  892. r=buf[8+12];    //ポート0のチャネル
  893. if ( r!=1 ){
  894.     //モノラルだった ステレオに
  895.     buf[12+8]=0x01;
  896.     buf[12+10]=0x02;
  897. } else {
  898.     //ステレオだった モノラルに
  899.     buf[12+8]=0x03;
  900.     buf[12+10]=0x03;
  901. }
  902. buf[2+12]=4;
  903. buf[8]= buf[9]= buf[10]= buf[11]= 0;
  904. if ( scsi_modeselect(0x10,16+4,SCSI_IDF,&buf[8])<0 )
  905.     return(-1);
  906. return(r);
  907. }
  908. /***************************************
  909.     CD-ROM接続チェック
  910. [戻り値] 0:OK
  911.     -1:
  912. ***************************************/
  913. int    CDROM_chk()
  914. {
  915. int    i;
  916. i=DEVICE_chk();
  917. if ( i!=0 )
  918.     return(i);
  919. /* 装置動作可能かチェック */
  920.                 //i=1はCDC特有の戻り値なのだ
  921. //REQU_PTR
  922. i=scsi_testunit(SCSI_IDF);
  923. if( i==0 || i==1 ){
  924.     return(0);    //puts("OK! 1\n\r");
  925. }
  926. i=scsi_testunit(SCSI_IDF);
  927. if( i==0 || i==1 ){
  928.     return(0);    //puts("OK! 2\n\r");
  929. }
  930. i=scsi_testunit(SCSI_IDF);
  931. if( i==0 || i==1 ){
  932.     return(0);    //puts("OK! 3\n\r");
  933. }
  934. if ( DeviType==0x10 ){
  935.     if ( i==2 && REQU_PTR_ASC==0x00 && (REQU_PTR_ASCQ>=0x11 && REQU_PTR_ASCQ<=0x15) )
  936.         return(0);    //puts("OK! 3\n\r");
  937. }
  938. //puts("指定された CD-ROM が準備されていません。\n\r");
  939. return(-2);
  940. }
  941. /***************************************
  942.     DEVICE チェック!
  943. ***************************************/
  944. int    DEVICE_chk()
  945. {
  946. int    i;
  947. UNchar buf[0x24];
  948. DeviType=5;
  949. /* メディアチェック */
  950. i=scsi_inquiry( 0x24, SCSI_IDF, (struct _inquiry *)buf );
  951. for(;i==8;)
  952.     i=scsi_inquiry( 0x24, SCSI_IDF, (struct _inquiry *)buf );
  953. if( SWPD==0 ){
  954.     if ( i!=0 ){
  955.         //puts("指定された SCSI-ID の装置は、現在動作不可能です。\n\r");
  956.         return(-3);
  957.     }
  958.     if ( buf[8]=='S' && buf[9]=='O' && buf[10]=='N' && buf[11]=='Y' 
  959.      && buf[16]=='M' && buf[17]=='D' && (buf[0]==7||buf[0]==0x10) ){
  960.         /* MDDATA だ!!*/
  961.         buf[0]=0x10;        //5or4=CD-ROM 0x10=MD
  962.     } else if ( buf[0]!=0x05 && buf[0]!=0x04 ){
  963.         //puts("指定された SCSI-ID の装置は、CD-ROM ではない。\n\r");
  964.         return(-1);
  965.     }
  966. } else if ( i!=0 ){    //PD対策
  967.     //puts("指定された SCSI-ID の装置は、現在動作不可能です。\n\r");
  968.     return(-3);
  969. }
  970. DeviType=buf[0];
  971. return(0);
  972. }
  973.